
import {
  wx_appid,
  wx_secret,
  wx_api,
  wx_public_params_list,
  wx_api_pay,
  wx_mchid,
  wx_serial_no,
  privateKey,
  wx_appid_yz_zuozhedua,
  wx_secret_yz_zuozhedua,
} from '../setting'

import {
  get,
  post
} from 'request'


const EncodingAESKey = 'COuv3lLu6pETIHt9Y7HHve4ZxecgXcRt1CM13U62uTG'
import { RedisInstance } from './redis';
import utils from './utils';
import token from './token';
const wx_access_key = 'wx_access_token'
const wx_access_key_yz_zuozheduan = 'wx_access_token_yz_zuozheduan'

export class WXAPI {
  token = 'jTx3MlPQrsuQoqExZ0fe6Fwu8ZQ2zCEZ'
  redis = undefined
  constructor(){
  }


  getRedis(){
    if(!this.redis){
      const redis = RedisInstance.initRedis();
      this.redis = redis
    }
    return this.redis
  }
  
  
  async clearPayWallet(wx_user){
    const redis = this.getRedis()
    await redis.expire(utils.redis_payconsumption_key + wx_user,0)
  }

  getWallet(wx_user){
    const redis = this.getRedis()
    return redis.get(utils.redis_payconsumption_key + wx_user)
  }


  /**
   * 校验图片合法性
   * @param content
   * @param wx_user
   * @returns
   */
   async mediaCheckAsync(media_url: string,wx_user: string){
    let accessToken = await this.getAccessToken()
    return new Promise((resolve,reject) => {
      const requestData = {
        media_url:media_url,
        media_type:2,
        version:2,
        scene:2,
        openid:wx_user,
      }
      post({
        url: `${wx_api}/wxa/media_check_async?access_token=${accessToken}`,
        method: "POST",
        json: true,
        headers: {
          "content-type": "application/json",
        },
        body: requestData
      }, async function(error, response, body) {
        if (!error && response.statusCode == 200) {
          console.log(body,'mediaCheckAsync body')
          let tokenResult = typeof(body) === 'string' ? JSON.parse(body) : body
          if(tokenResult && tokenResult.errcode == 0){
            resolve(tokenResult)
          }else{
            resolve({})
          }
        }else{
          resolve({})
        }
      })
    })
  }

  /**
   * 校验文本合法性
   * @param content
   * @param wx_user
   * @returns
   */
  async msgSecCheck(content: string,wx_user: string){
    let accessToken = await this.getAccessToken()
    return new Promise((resolve,reject) => {
      const requestData = {
        content:content,
        version:2,
        scene:2,
        openid:wx_user,
      }
      post({
        url: `${wx_api}/wxa/msg_sec_check?access_token=${accessToken}`,
        method: "POST",
        json: true,
        headers: {
          "content-type": "application/json",
        },
        body: requestData
      }, async function(error, response, body) {
        if (!error && response.statusCode == 200) {
          console.log(body,'token')
          let tokenResult = typeof(body) === 'string' ? JSON.parse(body) : body
          if(tokenResult){
            resolve(tokenResult)
          }
        }
      })
    })
  }

  async generatescheme(query){
    const redis:any = this.getRedis()
    let findAccessKey = await redis.get(wx_access_key)
    if(!findAccessKey){
      findAccessKey = await this.getAccessToken()
    }
    return new Promise((resolve,reject) => {
      post({
        url:`${wx_api}/wxa/generatescheme?access_token=${findAccessKey}`,
        method:'post',
        json: true,
        body:{
          jump_wxa:{
            path:'/pages/index/index',
            env_version: 'trial',
            query:query
          }
        }
      },(error, response, body) => {
        console.log(error,'err', body)
        if (!error && response.statusCode == 200) {
          let result = body
          resolve(result.openlink)
        }else{
          resolve('')
        }
      })
    })
  }
  
  async generatescheme_yz_zuozheduan(query){
    const redis:any = this.getRedis()
    let findAccessKey = await redis.get(wx_access_key_yz_zuozheduan)
    if(!findAccessKey){
      findAccessKey = await this.getAccessToken(wx_access_key_yz_zuozheduan, wx_appid_yz_zuozhedua, wx_secret_yz_zuozhedua)
    }
    return new Promise((resolve,reject) => {
      post({
        url:`${wx_api}/wxa/generatescheme?access_token=${findAccessKey}`,
        method:'post',
        json: true,
        body:{
          jump_wxa:{
            path:'/pages/create/create',
            env_version: 'trial',
            query:query
          }
        }
      },(error, response, body) => {
        console.log(error,'err', body)
        if (!error && response.statusCode == 200) {
          let result = body
          resolve(result.openlink)
        }else{
          resolve('')
        }
      })
    })
  }

  /**
   * 获取access-token
   * @returns
   */
  async getAccessToken(wx_access_key_temp?: any, wx_appid_temp?: any, wx_secret_temp?: any){
    wx_access_key_temp = wx_access_key_temp || wx_access_key
    const redis:any = this.getRedis()
    let findAccessKey = await redis.get(wx_access_key_temp)
    if(findAccessKey){
      return findAccessKey
    }
    return new Promise((resolve,reject) => {
      get(`${wx_api}/cgi-bin/token?grant_type=client_credential&appid=${wx_appid_temp || wx_appid}&secret=${wx_secret_temp || wx_secret}`,async (error, response, body) => {
        console.log(error,'err')
        if (!error && response.statusCode == 200) {
          let tokenResult = JSON.parse(body)
          if(tokenResult?.access_token){
            await redis.set(wx_access_key_temp, tokenResult.access_token)
            await redis.expire(wx_access_key_temp,tokenResult.expires_in - 20)
            resolve(tokenResult.access_token)
          }else{
            resolve('')
          }
        }else{
          resolve('')
        }
      })
    })
  }

  /**
   * 获取公众号的access-token
   * @returns
   */
   async getAccessToken_Public(code){
    return new Promise((resolve,reject) => {
      get(`${wx_api}/sns/oauth2/access_token?appid=${wx_public_params_list.appid}&secret=${wx_public_params_list.secret}&code=${code}&grant_type=authorization_code`,async (error, response, body) => {
        if (!error && response.statusCode == 200) {
          let result = JSON.parse(body)
          if(result.openid){
            resolve({
              access_token:result.access_token,
              openid:result.openid
            })
          }else{
            reject('未获取到信息')
          }
        }else{
          reject(error || '未获取到信息。')
        }
      })
    })
  }

  /**
   * 获取公众号的unionid
   * @returns
   */
   async getUnionId_Public(access_token,openid){
    return new Promise((resolve,reject) => {
      get(`${wx_api}/sns/userinfo?access_token=${access_token}&openid=${openid}&lang=zh_CN`,async (error, response, body) => {
        if (!error && response.statusCode == 200) {
          let result = JSON.parse(body)
          if(result.unionid){
            resolve({
              unionid:result.unionid,
            })
          }else{
            reject('未获取到公众号unionid')
          }
        }else{
          reject(error || '未获取到公众号unionid。')
        }
      })
    })
  }

  /**
   * 退换金额
   * @param wx_user 
   * @param openid 
   * @param unit_price 
   * @returns 
   */
  async refunds(wx_user, orderid, unit_price: number){
    return new Promise((resolve,reject) => {
      let requestData = {
        "out_trade_no":orderid,
        "reason": "返还悬赏",
        "out_refund_no": `refund${utils.Format(new Date(), 'yyyyMMddhhmmss')+utils.randomString(12)}`,
        "amount": {
          "refund": Number(unit_price),
          "total": Number(unit_price),
          "currency": "CNY"
        },
      }
      let signInfo:any = token.transfer(wx_mchid, wx_serial_no, privateKey, requestData, '/v3/refund/domestic/refunds')
      post({
        url: `${wx_api_pay}/refund/domestic/refunds`,
        method: "POST",
        json: true,
        headers: {
          "Content-Type":"application/json",
          "Authorization": `WECHATPAY2-SHA256-RSA2048 ${signInfo.signInfo}`,
          "User-Agent":"application/json",
          "Accept":"application/json"
        },
        body: requestData
      },(error, response, body) => {
        console.log(error, body)
        if (!error) {
          if(body.status === 'SUCCESS' || body.status === 'PROCESSING'){
            resolve(orderid)
          }else{
            reject(body.message)
          }
        }else{
          reject(error)
        }
      })
    })
  }
}
